package pers.zb.center.web.boss.controller.sys;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import pers.zb.center.common.core.enums.Status;
import pers.zb.center.common.core.util.DateUtil;
import pers.zb.center.common.core.util.JsonUtil;
import pers.zb.center.common.core.vo.AjaxResult;
import pers.zb.center.common.core.vo.JQDatatableResult;
import pers.zb.center.common.core.vo.Pager;
import pers.zb.center.common.core.vo.ZtreeVo;
import pers.zb.center.service.user.api.sys.AppService;
import pers.zb.center.service.user.api.sys.ReUserAppService;
import pers.zb.center.service.user.api.sys.RoleService;
import pers.zb.center.service.user.api.user.UserService;
import pers.zb.center.service.user.entity.sys.SysApp;
import pers.zb.center.service.user.entity.sys.SysReUserApp;
import pers.zb.center.service.user.entity.sys.SysRole;
import pers.zb.center.service.user.entity.sys.SysUser;
import pers.zb.center.service.user.enums.UserStatus;
import pers.zb.center.service.user.qo.sys.AppQo;
import pers.zb.center.service.user.qo.sys.UserQo;
import pers.zb.center.service.user.vo.sys.AppVo;
import pers.zb.center.service.user.vo.sys.RoleVo;
import pers.zb.center.service.user.vo.sys.UserVo;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;


/**
 * 
 * 用户管理
 * 
 * 创建日期：2016年8月13日 下午4:07:01 操作用户：zhoubang
 *
 */
@Controller
@RequestMapping("/user")
public class UserController {

    private Logger LOGGER = LoggerFactory.getLogger(getClass());

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private AppService appService;
    
    @Autowired
    private ReUserAppService reUserAppService;
    
    /**
     * 进入用户列表页面
     * 
     * 日期：2016年8月13日 下午4:07:06 用户：zhoubang
     * 
     * @param request
     * @param response
     */
    @RequestMapping("/toUserListView")
    @RequiresPermissions("user:list")
    public String toUserListView(HttpServletRequest request, HttpServletResponse response, ModelMap map) {

        // 账户状态
        map.put("status", UserStatus.values());

        // 所有角色
        List<SysRole> roles = roleService.getAllList();
        map.put("roles", roles);

        //应用系统列表
        Pager<AppVo> pager = new Pager<AppVo>();
        pager.setLimit(Integer.MAX_VALUE);
        AppQo appQo = new AppQo();
        appQo.setStatus(Status.ENABLE);
        Pager<AppVo> vos = appService.getList(pager,appQo);
        map.put("apps", vos.getRows());

        List<ZtreeVo> allApps = appService.queryAllFormatWithZtree(false,vos.getRows());
        // json字符串包含角色的复选框选中属性设置以及展开属性设置.
        map.put("allApps", JsonUtil.toJson(setPZtreeCheck(allApps, null, null)));

        return "sys/user/list";
    }

    @RequestMapping("/list")
    @RequiresPermissions("user:list")
    @ResponseBody
    public JQDatatableResult<UserVo> list(@ModelAttribute Pager<UserVo> pager, @ModelAttribute UserQo userQo) {
        pager = userService.getList(pager, userQo);

        JQDatatableResult<UserVo> result = new JQDatatableResult<UserVo>();
        result.setData(pager.getRows());
        result.setRecordsTotal(pager.getTotal().intValue());
        result.setDraw(pager.getDraw());
        result.setRecordsFiltered(pager.getTotal().intValue());
        return result;
    }

    /**
     * bootstrap table 列编辑保存
     * 
     * 日期：2016年8月13日 下午11:52:00 用户：zhoubang
     * 
     * @param qo
     * @return
     */
    /*@RequestMapping("/editTableColumn")
    @ResponseBody
    public AjaxResult<String> editTableColumn(@ModelAttribute UserQo qo) {
        LOGGER.debug("bootstrap table 列编辑保存，qo参数：userId:" + qo.getUserId() + "，realName：" + qo.getRealName());

        AjaxResult<String> result = new AjaxResult<String>();
        try {
            if (qo.getUserId() == null || "".equals(qo.getUserId())) {
                result.setCode(10001);
                result.setMsg("userId为空");
                return result;
            }

            SysUser user = userService.get(qo.getUserId());
            if (user == null) {
                result.setCode(10002);
                result.setMsg("该用户不存在");
                return result;
            }

            try {
                user.setRealName(qo.getRealName());
                user.setUpdateTime(new Date());
                userService.update(user);
            } catch (Exception e) {
                e.printStackTrace();
                result.setCode(10003);
                result.setMsg("保存失败");
                return result;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }*/

    /**
     * 删除用户
     * 
     * 日期：2016年8月20日 下午1:14:35 用户：zhoubang
     * 
     * @param qo
     * @return
     */
    @RequestMapping("/deleteUser")
    @RequiresPermissions("user:delete")
    @ResponseBody
    public AjaxResult<String> deleteUser(@ModelAttribute UserQo qo) {
        LOGGER.debug("删除用户，qo参数：userQo:" + JsonUtil.toJson(qo));

        AjaxResult<String> result = new AjaxResult<String>();
        try {
            // 删除用户与角色
            result = userService.deleteUser(qo.getUserId());
        } catch (Exception e) {
            e.printStackTrace();

            result.setCode(10003);
            result.setMsg("删除失败");
            return result;
        }
        return result;
    }
    
    /**
     * 批量删除用户
     * @param qo
     * @return
     */
    @RequestMapping("/deleteUsers")
    @RequiresPermissions("user:delete")
    @ResponseBody
    public AjaxResult<String> deleteUsers(@ModelAttribute UserQo qo) {
        LOGGER.debug("删除用户，qo参数：userQo:" + JsonUtil.toJson(qo));

        AjaxResult<String> result = new AjaxResult<String>();
        try {
            // 删除用户与角色
            result = userService.deleteUsers(qo.getUserIdArr());
        } catch (Exception e) {
            e.printStackTrace();

            result.setCode(10003);
            result.setMsg("删除失败");
            return result;
        }
        return result;
    }
    
    /**
     * 进入用户信息编辑页面
     * 
     * 日期：2016年8月20日 下午2:00:09 用户：zhoubang
     * 
     * @param map
     * @return
     */
    @RequestMapping("/toEditView")
    @RequiresPermissions("user:edit")
    public String toEditView(ModelMap map, UserQo qo) {
        if (qo.getUserId() != null) {
            SysUser user = userService.get(qo.getUserId());
            map.put("user", user);// 用户信息
        }
        map.put("userStatus", UserStatus.values());// 账户状态
        return "/sys/user/edit";
    }

    /**
     * 对角色tree进行操作 对用户拥有的角色进行复选框选中的属性设置,并且展开对应的权限tree。
     * 
     * 作者: zhoubang 日期：2015年4月29日 上午9:52:16
     * 
     * @param list
     *            所有角色列表
     * @param roleList
     *            用户拥有的角色列表
     * @param chkDisabledRoleIds
     * @return
     */
    public static List<ZtreeVo> setPZtreeCheck(List<ZtreeVo> list, List<SysRole> roleList,
                                               List<Long> chkDisabledRoleIds) {
        for (ZtreeVo ztreeVo : list) {
            if (roleList != null) {
                for (SysRole role : roleList) {
                    if (StringUtils.equals(String.valueOf(role.getId()), ztreeVo.getId())) {
                        ztreeVo.setChecked(true);
                    }
                    // 设置需要禁用check复选框选中的节点
                    if (null != chkDisabledRoleIds) {
                        for (Long roleId : chkDisabledRoleIds) {
                            if (role.getId().longValue() == roleId.longValue()) {
                                ztreeVo.setChkDisabled(true);
                            }
                        }
                    }
                }
            } else {
                ztreeVo.setChecked(false);
            }

            ztreeVo.setOpen(true);
        }
        return list;
    }

    /**
     * 更新用户信息
     * 
     * 日期：2016年8月20日 下午3:01:42 用户：zhoubang
     * 
     * @param qo
     * @return
     */
    @RequestMapping("/updateUser")
    @RequiresPermissions("user:update")
    @ResponseBody
    public AjaxResult<String> updateUser(@ModelAttribute UserQo qo) {
        LOGGER.debug("更新用户，qo参数：userQo:" + JsonUtil.toJson(qo));

        AjaxResult<String> result = new AjaxResult<String>();

        if (qo.getUserId() == null || "".equals(qo.getUserId())) {
            result.setCode(10001);
            result.setMsg("userId为空");
            return result;
        }

        SysUser user = userService.get(qo.getUserId());
        if (user == null) {
            result.setCode(10002);
            result.setMsg("该用户不存在");
            return result;
        }

        if (StringUtils.isBlank(qo.getRealName())) {
            result.setCode(10003);
            result.setMsg("用户名不能为空");
            return result;
        }

        try {
            // 更新用户信息
            userService.updateUser(user, qo);
        } catch (Exception e) {
            e.printStackTrace();

            result.setCode(10005);
            result.setMsg("更新失败");
            return result;
        }
        return result;
    }

    /**
     * 进入添加用户页面
     * 
     * 日期：2016年8月20日 下午4:26:07 用户：zhoubang
     * 
     * @param map
     * @return
     */
    @RequestMapping("/toAddView")
    @RequiresPermissions("user:add")
    public String toAddView(ModelMap map) {
        // 获取所有角色列表
        List<ZtreeVo> allRole = roleService.queryAllFormatWithZtree(false, false);

        // json字符串包含角色的复选框选中属性设置以及展开属性设置.
        map.put("allRoles", JsonUtil.toJson(setPZtreeCheck(allRole, null, null)));

        map.put("userStatus", UserStatus.values());

        //应用系统列表
        Pager<AppVo> pager = new Pager<AppVo>();
        pager.setLimit(Integer.MAX_VALUE);
        AppQo appQo = new AppQo();
        appQo.setStatus(Status.ENABLE);
        Pager<AppVo> vos = appService.getList(pager,appQo);
        map.put("apps", vos.getRows());

        return "/sys/user/add";
    }
    

    /**
     * 保存用户
     * 
     * 日期：2016年8月20日 下午4:39:13 用户：zhoubang
     * 
     * @param qo
     * @return
     */
    @RequestMapping("/addUser")
    @RequiresPermissions("user:add")
    @ResponseBody
    public AjaxResult<String> addUser(@ModelAttribute UserQo qo) {
        LOGGER.debug("新增用户，qo参数：userQo:" + JsonUtil.toJson(qo));

        AjaxResult<String> result = new AjaxResult<String>();

        if (StringUtils.isBlank(qo.getUserName())) {
            result.setCode(10001);
            result.setMsg("账户名不能为空");
            return result;
        }

        if (StringUtils.isBlank(qo.getRealName())) {
            result.setCode(10002);
            result.setMsg("姓名不能为空");
            return result;
        }

        if (qo.getStatus() == null) {
            result.setCode(10003);
            result.setMsg("请选择账户状态");
            return result;
        }

        if (qo.getAppId() == null) {
            result.setCode(10004);
            result.setMsg("请选择应用");
            return result;
        }
        SysUser sysUser = userService.getUserByName(qo.getUserName());
        if(sysUser != null){
            result.setCode(10006);
            result.setMsg("当前账户名已经存在");
            return result;
        }
        // 保存用户
        try {
            userService.saveUser(qo);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(10005);
            result.setMsg("添加失败");
            return result;
        }
        return result;
    }
    
    
    /**
     * 进入为用户分配应用的页面
     * 
     * 创建日期：2017年9月9日  下午4:24:50
     * 操作用户：zhoubang
     * 
     * @param map
     * @return
     * @throws Exception 
     */
    @RequestMapping("/toUserAssignAppView")
    @RequiresPermissions("user:assign:app")
    public String toUserAssignAppView(ModelMap map,Long userId) throws Exception {
        // 获取所有系统列表
        List<SysApp> allApp = appService.getAllList();
        
        //获取已经分配的应用
        List<SysReUserApp> userAppList = reUserAppService.getAppsByUserId(userId);
        
        map.put("userAppList", userAppList);
        map.put("userId", userId);
        map.put("allApp", allApp);
        return "/sys/user/assign_app";
    }
    
    /**
     * 分配应用
     * 
     * 创建日期：2017年9月9日  下午5:14:59
     * 操作用户：zhoubang
     * 
     * @param userQo
     * @return
     */
    @RequestMapping("/assignApp")
    @RequiresPermissions("user:assign:app")
    @ResponseBody
    public AjaxResult<String> assignApp(@ModelAttribute UserQo userQo) {
        AjaxResult<String> result = new AjaxResult<String>();
        
        try {
            result = reUserAppService.assignApp(userQo);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(10001);
            result.setMsg("分配应用失败");
            return result;
        }
        return result;
    }
    
    
    /**
     * 进入为用户分配角色的页面
     * 
     * 创建日期：2017年9月9日  下午4:24:50
     * 操作用户：zhoubang
     * 
     * @param map
     * @return
     * @throws Exception 
     */
    @RequestMapping("/toUserAssignRoleView")
    @RequiresPermissions("user:assign:role")
    public String toUserAssignRoleView(ModelMap map,Long userId) throws Exception {
        // 获取所有应用列表
        //List<SysApp> allApp = appService.getAllAppForOrderBy("sort", "asc");

        //获取用户信息
        SysUser user = userService.getUserById(userId);
        map.put("user", user);
        map.put("statusName",user.getStatus().getDescription());
        map.put("createTime", DateUtil.getDateTimeFormat(user.getCreateTime()));
        map.put("updateTime", DateUtil.getDateTimeFormat(user.getUpdateTime()));
        map.put("haveRoles", roleService.getUserRoles(user.getUserName()));

        SysApp app =null;
        List<SysReUserApp> userApps = reUserAppService.getAppsByUserId(userId);//获取用户所属的应用。用户只属于一个应用下。此方法是以前所写
        if(userApps != null && userApps.size() > 0){
            app = appService.get(userApps.get(0).getAppId());
            map.put("userApp",app);


        }

        /**
         * 获取可用状态的角色
         */
        Pager<RoleVo> pager = new Pager<RoleVo>();
        SysRole sysRole = new SysRole();
        sysRole.setStatus(Status.ENABLE);//可用状态的角色
        sysRole.setAppId(app.getId());//获取该应用下的角色
        Pager<RoleVo> vos = roleService.getList(pager,sysRole);
        for (RoleVo vo:vos.getRows()) {
            System.out.println("可用状态的角色：" + vo.getId() + "\t" + vo.getName() + "\t" + vo.getAppId());
        }

        //获取该用户拥有的角色
        List<SysRole> roleList = roleService.getUserRoles(user.getUserName());
        for (SysRole r:roleList) {
            System.out.println("用户拥有的角色：" + r.getId() + "\t" + r.getName() + "\t" + r.getAppId());
        }
        map.put("roleList", roleList);
        if(roleList == null || roleList.size() <= 0){//说明还未指定角色
            List<RoleVo> allRoles = new ArrayList<RoleVo>();
            for (RoleVo vo : vos.getRows()) {
                allRoles.add(vo);
            }
            map.put("allRoles", allRoles);//用户未拥有的角色
        }else {
            List<RoleVo> allRoles = new ArrayList<RoleVo>();
            for (RoleVo vo : vos.getRows()) {
                Boolean bool = false;
                for (SysRole role:roleList) {
                    if(!vo.getId().equals(String.valueOf(role.getId()))){
                        bool = true;
                    }else{
                        bool = false;
                        break;
                    }
                }
                if(bool){
                    allRoles.add(vo);
                }
            }
            map.put("allRoles", allRoles);//用户未拥有的角色
        }



        return "/sys/user/assign_role";
    }
    
    /**
     * 为用户分配某个应用下的角色
     * 
     * 创建日期：2017年9月9日  下午11:17:01
     * 操作用户：zhoubang
     * 
     * @param userQo
     * @return
     */
    @RequestMapping("/assignRole")
    @RequiresPermissions("user:assign:role")
    @ResponseBody
    public AjaxResult<String> assignRole(UserQo userQo) {
        AjaxResult<String> result = new AjaxResult<String>();
        
        try {
            result = reUserAppService.assignRole(userQo);
        } catch (Exception e) {
            e.printStackTrace();
            result.setCode(10001);
            result.setMsg("分配角色失败");
            return result;
        }
        return result;
    }
}
